package com.ext.aic.adapter;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.Glide;
import com.ext.aic.R;
import com.ext.aic.beans.Attachment;
import com.ext.aic.beans.CustomMedia;
import com.ext.aic.beans.MenuItem;
import com.ext.aic.components.MenuBottomPopup;
import com.ext.aic.constants.EBusConstants;
import com.ext.aic.databinding.NinePictureItemBinding;
import com.ext.aic.enums.EditNineSource;
import com.ext.aic.enums.ImageStatus;
import com.ext.aic.events.AttachmentUploadCallback;
import com.ext.aic.holder.NineItemViewHolder;
import com.ext.aic.ui.AIGenerateImageActivity;
import com.ext.aic.utils.PictureUtils;
import com.ext.aic.utils.RedirectUtils;
import com.ext.aic.utils.XPopupUtils;
import com.eyinfo.android_pure_utils.ebus.EBus;
import com.eyinfo.android_pure_utils.ebus.SubscribeEBus;
import com.eyinfo.android_pure_utils.events.Action1;
import com.eyinfo.android_pure_utils.utils.ConvertUtils;
import com.eyinfo.android_pure_utils.utils.ModelConvert;
import com.eyinfo.android_pure_utils.utils.ObjectJudge;
import com.eyinfo.android_pure_utils.utils.PixelUtils;
import com.luck.picture.lib.entity.LocalMedia;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import lombok.Setter;

@SuppressLint("NotifyDataSetChanged")
public class NinePictureAdapter extends RecyclerView.Adapter<NineItemViewHolder> implements AttachmentUploadCallback<Long> {

    private List<CustomMedia> images = new ArrayList<>();
    private Map<Long, CustomMedia> imageMap = new HashMap<>();
    private Context context;
    private int MAX_IMAGES = 9;
    private int itemSize;
    private boolean onlyPreview;
    @Setter
    private EditNineSource nineSource;

    public NinePictureAdapter(Context context, int maxWidth, boolean onlyPreview) {
        this.context = context;
        this.itemSize = (maxWidth - PixelUtils.dip2px(context, 8)) / 3;
        this.onlyPreview = onlyPreview;
        EBus.getInstance().registered(this, String.valueOf(hashCode()));
    }

    public void setAttachments(List<Attachment> attachments) {
        if (onlyPreview) {
            initPreviewImage(attachments);
        } else if (!ObjectJudge.isNullOrEmpty(attachments)) {
            for (Attachment attachment : attachments) {
                CustomMedia media = new CustomMedia();
                media.setId(attachment.getId().hashCode());
                media.setFileName(attachment.getFilename());
                media.setPath(attachment.getFileUrl());
                images.add(media);
            }
        }
    }

    private void initPreviewImage(List<Attachment> attachments) {
        if (attachments == null || attachments.isEmpty()) {
            return;
        }
        images.clear();
        for (Attachment attachment : attachments) {
            CustomMedia media = new CustomMedia();
            media.setId(attachment.getId().hashCode());
            media.setFileName(attachment.getFilename());
            media.setPath(attachment.getFileUrl());
            images.add(media);
        }
    }

    @Override
    public NineItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.nine_picture_item, parent, false);
        return new NineItemViewHolder(NinePictureItemBinding.bind(view));
    }

    @Override
    public void onBindViewHolder(NineItemViewHolder holder, int position) {
        if (!onlyPreview && position == images.size() && images.size() < MAX_IMAGES) {
            holder.itemRl.setVisibility(View.GONE);
            holder.itemAddLl.setVisibility(View.VISIBLE);
            ViewGroup.LayoutParams layoutParams = holder.itemAddLl.getLayoutParams();
            layoutParams.width = itemSize;
            layoutParams.height = itemSize;
            holder.itemAddLl.setLayoutParams(layoutParams);
            holder.itemAddLl.setOnClickListener(this::onAddImageClick);
        } else {
            holder.itemAddLl.setVisibility(View.GONE);
            holder.itemRl.setVisibility(View.VISIBLE);
            ViewGroup.LayoutParams layoutParams = holder.itemRl.getLayoutParams();
            layoutParams.width = itemSize;
            layoutParams.height = itemSize;
            holder.itemRl.setLayoutParams(layoutParams);

            CustomMedia media = images.get(position);
            Glide.with(context)
                    .load(media.getPath())
                    .into(holder.itemRiv);
            if (onlyPreview) {
                holder.delFl.setVisibility(View.GONE);
                holder.itemRl.setTag(position);
                holder.itemRl.setOnClickListener(this::onItemClick);
            } else {
                holder.delFl.setTag(position);
                holder.delFl.setOnClickListener(this::onDelClick);
                bindImageUploadChange(holder, media, position);
            }
        }
    }

    public void onItemClick(View view) {
        int position = ConvertUtils.toInt(view.getTag());
        EBus.getInstance().post(EBusConstants.previewImage, position, images);
    }

    private void bindImageUploadChange(NineItemViewHolder holder, CustomMedia media, int position) {
        if (media.getStatus() == ImageStatus.normal) {
            holder.maskRl.setVisibility(View.VISIBLE);
            holder.delFl.setVisibility(View.VISIBLE);
            holder.progressTv.setVisibility(View.VISIBLE);
            holder.progressTv.setText(R.string.waiting_upload);
        } else if (media.getStatus() == ImageStatus.uploading) {
            holder.maskRl.setVisibility(View.VISIBLE);
            holder.delFl.setVisibility(View.GONE);
            holder.failRl.setVisibility(View.GONE);
            holder.imageIndicator.setVisibility(View.VISIBLE);
            holder.progressTv.setVisibility(View.VISIBLE);
            holder.imageIndicator.setProgress(media.getPercent());
            holder.progressTv.setText(MessageFormat.format("{0}%", media.getPercent()));
        } else if (media.getStatus() == ImageStatus.uploadFailed) {
            holder.maskRl.setVisibility(View.VISIBLE);
            holder.failRl.setVisibility(View.VISIBLE);
            holder.failRl.setTag(position);
            holder.failRl.setOnClickListener(this::onReUploadClick);
            holder.failIv.setTag(position);
            holder.failIv.setOnClickListener(this::onReUploadClick);
            holder.delFl.setVisibility(View.VISIBLE);
            holder.imageIndicator.setVisibility(View.GONE);
            holder.progressTv.setVisibility(View.GONE);
            holder.reUploadTv.setTag(position);
            holder.reUploadTv.setOnClickListener(this::onReUploadClick);
        } else if (media.getStatus() == ImageStatus.uploadSuccess ||
                media.getPercent() == 100) {
            holder.maskRl.setVisibility(View.GONE);
            holder.delFl.setVisibility(View.VISIBLE);
        }
    }

    @Override
    public int getItemCount() {
        if (onlyPreview) {
            return images.size();
        }
        return Math.min(images.size() + 1, MAX_IMAGES);
    }

    public void onReUploadClick(View view) {
        int position = ConvertUtils.toInt(view.getTag());
        CustomMedia media = images.get(position);
        EBus.getInstance().post(EBusConstants.reUploadImage, media, this);
    }

    @SuppressLint("NotifyDataSetChanged")
    public void onDelClick(View view) {
        String title = context.getString(R.string.delete_tip);
        String content = context.getString(R.string.delete_image_tip);
        XPopupUtils.getInstance().showConfirmDialog(context, title, content, false, () -> {
            int position = ConvertUtils.toInt(view.getTag());
            if (position >= 0 && position < images.size()) {
                LocalMedia remove = images.remove(position);
                notifyDataSetChanged();
                EBus.getInstance().post(EBusConstants.delImage, remove.getId());
            }
        });
    }

    public void onAddImageClick(View view) {
        List<MenuItem> items = new ArrayList<>();
        items.add(new MenuItem("照片图库", false));
        items.add(new MenuItem("AI生图", false));
        MenuBottomPopup bottomPopup = new MenuBottomPopup(context, items);
        bottomPopup.setItemClickCall((item) -> {
            if (TextUtils.equals(item.getName(), "照片图库")) {
                openPicture();
            } else {
                Bundle bundle = new Bundle();
                bundle.putInt("nineTag", this.hashCode());
                RedirectUtils.getInstance().startActivity(context, AIGenerateImageActivity.class, bundle);
            }
        });
        XPopupUtils.getInstance().showBottomDialog(context, bottomPopup);

        //添加图片弹窗
        EBus.getInstance().post(EBusConstants.addImageDialog);
    }

    private void openPicture() {
        int rawImageCount = images.size();
        PictureUtils.getInstance().showPicture(context, MAX_IMAGES - rawImageCount, list -> {
            if (list == null || list.isEmpty()) {
                return;
            }
            List<CustomMedia> models = ModelConvert.toModels(list, CustomMedia.class, new Action1<CustomMedia>() {
                @Override
                public void call(CustomMedia customMedia) {
                    imageMap.put(customMedia.getId(), customMedia);
                }
            });
            images.addAll(models);
            notifyDataSetChanged();
            EBus.getInstance().post(EBusConstants.selectedImageList, images, this);
        });
    }

    @Override
    public void onAttachmentStart(Long value) {
        CustomMedia media = imageMap.get(value);
        media.setStatus(ImageStatus.normal);
        notifyDataSetChanged();
    }

    @Override
    public void onAttachmentFailure(Long value) {
        CustomMedia media = imageMap.get(value);
        media.setStatus(ImageStatus.uploadFailed);
        notifyDataSetChanged();
    }

    @Override
    public void onAttachmentProgress(Long value, int percent) {
        CustomMedia media = imageMap.get(value);
        media.setStatus(ImageStatus.uploading);
        media.setPercent(percent);
        notifyDataSetChanged();
    }

    @Override
    public void onAttachmentSuccess(Long value, String resourceName, String url, String realPath, String attachmentId) {
        CustomMedia media = imageMap.get(value);
        media.setStatus(ImageStatus.uploadSuccess);
        notifyDataSetChanged();
        EBus.getInstance().post(EBusConstants.attachmentUpdateSuccess, value, resourceName, url, realPath, attachmentId);
    }

    @Override
    public void onAttachmentEnd(Long value) {

    }

    @SubscribeEBus(receiveKey = EBusConstants.receiveAiGenerateImage)
    public void onReceiveAIGenerateImageEvent(int nineTag, String fileName, String filePath) {
        CustomMedia media = new CustomMedia();
        media.setId(filePath.hashCode());
        media.setFileName(fileName);
        media.setPath(filePath);
        media.setRealPath(filePath);
        images.add(media);
        imageMap.put(media.getId(), media);
        notifyDataSetChanged();
        EBus.getInstance().post(EBusConstants.singleAiGenerateImage, media, this);
    }
}
